prepare for Qt 6.8 deprecations (#1346)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Tue, 8 Oct 2024 12:46:21 +0000 (06:46 -0600)
committerGitHub <noreply@github.com>
Tue, 8 Oct 2024 12:46:21 +0000 (06:46 -0600)
* fix Qt 6.8.0 deprecation warnings.

Also, the exif writer now prefers to establish a timestamp from
GPS_IFD_TAG_DATESTAMP/GPS_IFD_TAG_TIMESTAMP if they exist, as the
exif reader does.

* avoid installing *.debug_information modules

which appeared with 6.7.0

* centralize decision on lightweight time zones.

* correct sort order for includes, duplicates

* remove debug statement

* remove const from declaration.

* simplify lightweight timezone usage via

qt version depependent defined constants.

* fix for QTimeZone not a QLiteralType

* cleanup lightweight time constants.

* enhance exif offset test

* add missing reference

* fix test comment

* revert changes to exif writer regarding gps tags.

I beleive the original intent of the writer is to create the gps tags
from a waypoint.

* update qt modules

* qt 6.8 work

1. allow builds to succeed without webengine by default.  This is
needed by CI until aqt catches up.
2. macos minos change for 6.8
3. add macos 6.8.0 to CI, remove macos-12 build.

* avoid Wunused-const-variable

* add 6.8.0 to ci for windows

31 files changed:
.github/workflows/macos.yml
.github/workflows/windows.yml
CMakeLists.txt
defs.h
dg-100.cc
exif.cc
garmin_gpi.cc
gdb.cc
globalsat_sport.cc
gpx.cc
gui/CMakeLists.txt
gui/filterwidgets.cc
gui/upgrade.cc
igc.cc
lowranceusr.cc
mtk_logger.cc
nmea.cc
reference/ricoh-rdc5300.jpg.jpg
reference/ricoh-rdc5300_offset.csv [new file with mode: 0644]
reference/ricoh-rdc5300_offsettime.jpg [new file with mode: 0644]
reference/ricoh-rdc5300_offsettime.jpg.jpg [new file with mode: 0644]
skytraq.cc
src/core/datetime.h
subrip.cc
testo.d/exif.test
tools/ci_install_qt.sh
tools/ci_install_windows.sh
tools/ci_script_osx.sh
trackfilter.cc
util.cc
v900.cc

index 7a143ac0613f2a2677a4a81f98e358b755736456..998c82702ca96ddbd0a9e386cab1fc744260f2e8 100644 (file)
@@ -18,11 +18,6 @@ jobs:
       fail-fast: false
       matrix:
         include:
-          - QT_VERSION: '6.2.4'
-            XCODE_VERSION: '13.4.1'
-            GENERATOR: 'Ninja'
-            RELEASE: false
-            os: macos-12
           - QT_VERSION: '6.2.4'
             XCODE_VERSION: '14.3.1'
             GENERATOR: 'Ninja'
@@ -38,6 +33,11 @@ jobs:
             GENERATOR: 'Ninja'
             RELEASE: true
             os: macos-14
+          - QT_VERSION: '6.8.0'
+            XCODE_VERSION: '16.0'
+            GENERATOR: 'Ninja'
+            RELEASE: false
+            os: macos-15
 
     steps:
     - name: Checkout repository
index b37a74a0ddb8c090032e158f060cdcea088f5cbc..6b9d5d932792a12d79dda3d12a08bb326907c51e 100644 (file)
@@ -44,6 +44,14 @@ jobs:
             RELEASE: true
             GENERATOR: 'Ninja'
             os: windows-latest
+          - QT_VERSION: '6.8.0'
+            ARCH: 'amd64'
+            HOST_ARCH: 'amd64'
+            COMPILER: 'msvc2022_64'
+            METHOD: 'aqt'
+            RELEASE: false
+            GENERATOR: 'Ninja'
+            os: windows-latest
 
     steps:
     - name: Checkout repository
index 1a9a1df0dc046ec199b52f288ea8060c37e70971..c0841ee75fb233bce45d8a242c58030d0f54fe76 100644 (file)
@@ -33,6 +33,9 @@ if(${Qt6Core_VERSION} VERSION_LESS 6.2)
 else()
   message(STATUS "Using Qt6 version ${Qt6Core_VERSION}")
 endif()
+if(${Qt6Core_VERSION} VERSION_GREATER_EQUAL 6.5)
+  target_compile_definitions(gpsbabel PRIVATE LIGHTWEIGHT_TIMEZONES_SUPPORTED)
+endif()
 
 option(GPSBABEL_ENABLE_PCH "enable precompiled headers." ON)
 if (GPSBABEL_ENABLE_PCH)
diff --git a/defs.h b/defs.h
index 316468c2e08c59b53a92273719210f5118f2c6a4..84ecf4636d2f8fb070f7ba850c2a4eeda167f521 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -37,6 +37,9 @@
 #include <QString>                   // for QString
 #include <QStringView>               // for QStringView
 #include <QTextCodec>                // for QTextCodec
+#ifdef LIGHTWEIGHT_TIMEZONES_SUPPORTED
+#include <QTimeZone>                 // for QTimeZone
+#endif
 #include <Qt>                        // for CaseInsensitive
 #include <QtGlobal>                  // for QForeachContainer, qMakeForeachContainer, foreach, qint64
 
@@ -1042,4 +1045,12 @@ int color_to_bbggrr(const char* cname);
 constexpr double unknown_alt = -99999999.0;
 constexpr int unknown_color = -1;
 
+#ifdef LIGHTWEIGHT_TIMEZONES_SUPPORTED
+constexpr QTimeZone::Initialization QtLocalTime = QTimeZone::LocalTime;
+constexpr QTimeZone::Initialization QtUTC = QTimeZone::UTC;
+#else
+constexpr Qt::TimeSpec QtLocalTime = Qt::LocalTime;
+constexpr Qt::TimeSpec QtUTC = Qt::UTC;
+#endif
+
 #endif // DEFS_H_INCLUDED_
index 53bc50fd8b6f66646ca3352040b09b924afdf058..3279daeaebfbfc394229b8301df5e465943c1c04 100644 (file)
--- a/dg-100.cc
+++ b/dg-100.cc
@@ -109,7 +109,7 @@ Dg100Format::bintime2utc(int date, int time)
   date /= 100;
   int day  = date;
 
-  return QDateTime(QDate(year, mon, day), QTime(hour, min, sec), Qt::UTC);
+  return QDateTime(QDate(year, mon, day), QTime(hour, min, sec), QtUTC);
 }
 
 void
diff --git a/exif.cc b/exif.cc
index c53a2db96c4ad7d24bd0573a8d15ff20997328e3..624f5b4edeea69fc610c2a1fd8b5240858e7f266 100644 (file)
--- a/exif.cc
+++ b/exif.cc
@@ -47,6 +47,9 @@
 #include <QString>              // for QString
 #include <QTextCodec>           // for QTextCodec
 #include <QTime>                // for QTime
+#ifdef LIGHTWEIGHT_TIMEZONES_SUPPORTED
+#include <QTimeZone>            // for QTimeZone
+#endif
 #include <QVariant>             // for QVariant
 #include <QVector>              // for QVector
 #include <Qt>                   // for UTC, ISODate
@@ -728,7 +731,11 @@ ExifFormat::exif_get_exif_time(ExifApp* app) const
         // Correct the date time by supplying the offset from UTC.
         int offset_hours = match.captured(1).append(match.captured(2)).toInt();
         int offset_mins = match.captured(1).append(match.captured(3)).toInt();
+#ifdef LIGHTWEIGHT_TIMEZONES_SUPPORTED
+        res.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(((offset_hours * 60) + offset_mins) * 60));
+#else
         res.setOffsetFromUtc(((offset_hours * 60) + offset_mins) * 60);
+#endif
       } else if (opt_offsettime) {
         // Only warn for user supplied offsets.
         // Offset tags may indicate the offset was unknown, e.g. "   :  ".
@@ -912,7 +919,7 @@ ExifFormat::exif_waypt_from_exif_app(ExifApp* app) const
     }
   }
 
-  gps_datetime = QDateTime(datestamp, timestamp, Qt::UTC);
+  gps_datetime = QDateTime(datestamp, timestamp, QtUTC);
   if (gps_datetime.isValid()) {
     if (global_opts.debug_level >= 3) {
       printf(MYNAME "-GPSTimeStamp =   %s\n", qPrintable(gps_datetime.toString(Qt::ISODateWithMs)));
index 745f68c2f6ce398e16334285cdc2c05c596ecc8e..3d0ee03321dfcb3c004c9115df7d51b573f0e1b0 100644 (file)
@@ -178,7 +178,7 @@ GarminGPIFormat::read_header()
   if (GPI_DBG) {
     time_t crdate = GPS_Math_Gtime_To_Utime(rdata->crdate);
     warning("crdate = %lld (%s)\n", (long long) rdata->crdate,
-            CSTR(QDateTime::fromSecsSinceEpoch(crdate, Qt::UTC).toString(Qt::ISODate)));
+            CSTR(QDateTime::fromSecsSinceEpoch(crdate, QtUTC).toString(Qt::ISODate)));
   }
 
   (void) gbfgetint16(fin);  /* 0 */
diff --git a/gdb.cc b/gdb.cc
index 67cd26aec96f128a7138bf33a3124ba52f9acad0..3b024e063741e4b9ae5952b04df3fca5eb5087d3 100644 (file)
--- a/gdb.cc
+++ b/gdb.cc
@@ -62,7 +62,7 @@ constexpr unsigned int GDB_DBG_TRK = 4;
 
 constexpr unsigned int GDB_DBG_WPTe = 8;
 constexpr unsigned int GDB_DBG_RTEe = 16;
-constexpr unsigned int GDB_DBG_TRKe = 32;
+//constexpr unsigned int GDB_DBG_TRKe = 32;
 
 //constexpr unsigned int GDB_DEBUG = (GDB_DBG_WPTe) /* | GDB_DBG_RTE) */;
 //constexpr unsigned int GDB_DEBUG = 0xff;
@@ -1126,7 +1126,7 @@ GdbFormat::write_header()
    * This is our "Watermark" to show this file was created by GPSbabel.
    * The date/time used to be from CVS, and may be from git in the future.
    */
-  static const QDateTime gdb_release_dt = QDateTime(QDate(2011, 4, 14), QTime(1, 30, 1), Qt::UTC);
+  static const QDateTime gdb_release_dt = QDateTime(QDate(2011, 4, 14), QTime(1, 30, 1), QtUTC);
   gdb_write_cstr(QStringLiteral("GPSBabel-%1").arg(gpsbabel_version));
   gdb_write_cstr(gdb_release_dt.toString(u"MMM dd yyyy"));
   gdb_write_cstr(gdb_release_dt.toString(u"HH:mm:ss"));
index 813586728e9cc4108b3bcdcfe128948c9ce0e1a1..e4a69c383cad740d93e18a3a4a3e8a17337045b6 100644 (file)
@@ -529,7 +529,7 @@ GlobalsatSportFormat::track_read()
           if (timezn != nullptr) {
             gpsDateTime = gpsbabel::DateTime(QDateTime(gpsDate, gpsTime, *timezn).toUTC());
           } else {
-            gpsDateTime = gpsbabel::DateTime(QDateTime(gpsDate, gpsTime, Qt::LocalTime).toUTC());
+            gpsDateTime = gpsbabel::DateTime(QDateTime(gpsDate, gpsTime, QtLocalTime).toUTC());
           }
 
           int laps_in_package = header.gh_laprec.LapIndex - header.gh_ptrec.Index + 1;
diff --git a/gpx.cc b/gpx.cc
index 96af32faada467001ea5d69a3d0f0215b467fdb7..080ad56598300c2cddd66735e2eef89229a44a2a 100644 (file)
--- a/gpx.cc
+++ b/gpx.cc
@@ -517,7 +517,7 @@ xml_parse_time(const QString& dateTimeString)
   if (res > 0) {
     QDate date(year, mon, mday);
     QTime time(hour, min, sec);
-    dt = QDateTime(date, time, Qt::UTC);
+    dt = QDateTime(date, time, QtUTC);
 
     // Fractional part of time.
     if (fsec) {
index 04e09549819d8b1df405555a46825cb8bb1c2950..dc4e0939c414749bca0c54deba4bc1d1042bc8c4 100644 (file)
@@ -22,7 +22,7 @@ if(NOT UNIX OR APPLE)
 endif()
 
 # Find the QtCore library
-find_package(Qt6 REQUIRED COMPONENTS Core Gui Network SerialPort Widgets Xml)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Network SerialPort Widgets Xml OPTIONAL_COMPONENTS WebEngineWidgets WebChannel)
 list(APPEND QT_LIBRARIES Qt6::Core Qt6::Gui Qt6::Network Qt6::SerialPort Qt6::Widgets Qt6::Xml)
 if(${Qt6Core_VERSION} VERSION_LESS 6.2)
   message(FATAL_ERROR "Qt version ${Qt6Core_VERSION} found, but version 6.2 or newer is required.")
@@ -30,11 +30,13 @@ else()
   message(STATUS "Using Qt6 version ${Qt6Core_VERSION}")
 endif()
 
-option(GPSBABEL_MAPPREVIEW "enable map preview." ON)
+cmake_dependent_option(GPSBABEL_MAPPREVIEW "enable map preview." ON "Qt6WebEngineWidgets_FOUND;Qt6WebChannel_FOUND" OFF)
 if (GPSBABEL_MAPPREVIEW)
-  find_package(Qt6 REQUIRED COMPONENTS WebEngineWidgets WebChannel)
   list(APPEND QT_LIBRARIES Qt6::WebEngineWidgets Qt6::WebChannel)
 else()
+  if (NOT Qt6WebEngineWidgets_FOUND OR NOT Qt6WebChannel_FOUND)
+    message(WARNING "Optional components Qt6 WebEngineWidgets and/or Qt6 WebChannel not found, MAPPREVIEW is not available.")
+  endif()
   target_compile_definitions(gpsbabelfe PRIVATE DISABLE_MAPPREVIEW)
 endif()
 
index 39426e171ae9a0ec209ba4661cb1d15376eec9d6..9600149a9cf9c3f4319612be874ef6228a9a5653 100644 (file)
@@ -30,6 +30,9 @@
 #include <QEvent>        // for QEvent, QEvent::LocaleChange
 #include <QLabel>        // for QLabel
 #include <QRadioButton>  // for QRadioButton
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
+#include <QTimeZone>     // for QTimeZone
+#endif
 #include <Qt>            // for LocalTime, UTC
 
 
@@ -75,17 +78,27 @@ TrackWidget::TrackWidget(QWidget* parent, TrackFilterData& tfd): FilterWidget(pa
   ui.startEdit->setDisplayFormat("dd MMM yyyy hh:mm:ss AP");
   ui.stopEdit->setDisplayFormat("dd MMM yyyy hh:mm:ss AP");
 
-  assert(tfd.startTime.timeSpec() == tfd.stopTime.timeSpec());
-  assert((tfd.startTime.timeSpec() == Qt::UTC) || (tfd.startTime.timeSpec() == Qt::LocalTime));
   // Qt5 QDateTimeEdit::setDateTime ignored the passed QDateTime::timeSpec.
   // Qt6 QDateTimeEdit::setDateTime will convert the passed QDateTime if the passed
   // QDateTime::timeSpec doesn't match QDateTimeEdit::timeSpec.
   // If the two timeSpecs match Qt5 and Qt6 behave the same.
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
+  assert(tfd.startTime.timeZone() == tfd.stopTime.timeZone());
+  assert((tfd.startTime.timeZone() == QTimeZone::UTC) || (tfd.startTime.timeZone() == QTimeZone::LocalTime));
+  ui.startEdit->setTimeZone(tfd.startTime.timeZone());
+  ui.stopEdit->setTimeZone(tfd.stopTime.timeZone());
+  // Make sure the initial state of the localTime and utc radio buttons
+  // is in agreement with the startTime::timeSpec and stopTime::timeSpec.
+  tfd.localTime = tfd.startTime.timeZone() == QTimeZone::LocalTime;
+#else
+  assert(tfd.startTime.timeSpec() == tfd.stopTime.timeSpec());
+  assert((tfd.startTime.timeSpec() == Qt::UTC) || (tfd.startTime.timeSpec() == Qt::LocalTime));
   ui.startEdit->setTimeSpec(tfd.startTime.timeSpec());
   ui.stopEdit->setTimeSpec(tfd.stopTime.timeSpec());
   // Make sure the initial state of the localTime and utc radio buttons
   // is in agreement with the startTime::timeSpec and stopTime::timeSpec.
   tfd.localTime = tfd.startTime.timeSpec() == Qt::LocalTime;
+#endif
   tfd.utc = !tfd.localTime;
 
   // Collect the data fields.
@@ -188,11 +201,21 @@ void TrackWidget::splitDistanceX()
 void TrackWidget::TZX()
 {
   if (ui.localTime->isChecked()) {
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
+    ui.startEdit->setTimeZone(QTimeZone::LocalTime);
+    ui.stopEdit->setTimeZone(QTimeZone::LocalTime);
+#else
     ui.startEdit->setTimeSpec(Qt::LocalTime);
     ui.stopEdit->setTimeSpec(Qt::LocalTime);
+#endif
   } else {
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
+    ui.startEdit->setTimeZone(QTimeZone::UTC);
+    ui.stopEdit->setTimeZone(QTimeZone::UTC);
+#else
     ui.startEdit->setTimeSpec(Qt::UTC);
     ui.stopEdit->setTimeSpec(Qt::UTC);
+#endif
   }
   // Force update of Edit displays, so the displayed
   // datetimes are in sync with the specified time spec.
index 73211c4cf279cb1e8c99a7b79abd4f60b54b1de4..3009b6a72aaea3d066a3822494ddf8040d60f620 100644 (file)
@@ -262,14 +262,20 @@ void UpgradeCheck::httpRequestFinished(QNetworkReply* reply)
   QString oresponse(reply->readAll());
 
   QDomDocument document;
-  int line = -1;
-  QString error_text;
   // This shouldn't ever be seen by a user.
-  if (!document.setContent(oresponse, &error_text, &line)) {
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
+  if (auto result = document.setContent(oresponse); !result) {
+#else
+  struct {
+    int errorLine{-1};
+    QString errorMessage;
+  } result;
+  if (!document.setContent(oresponse, &result.errorMessage, &result.errorLine)) {
+#endif
     QMessageBox::critical(nullptr, tr("Error"),
                           tr("Invalid return data at line %1: %2.")
-                          .arg(line)
-                          .arg(error_text));
+                          .arg(result.errorLine)
+                          .arg(result.errorMessage));
     babelData_.upgradeErrors_++;
     replyId_ = nullptr;
     reply->deleteLater();
diff --git a/igc.cc b/igc.cc
index 7ef925ee9633de9191b05739aa3e6521b7b28d6e..1b831a043a41f1561f409f38297db01cff6a3bc4 100644 (file)
--- a/igc.cc
+++ b/igc.cc
@@ -162,7 +162,7 @@ void IgcFormat::TaskRecordReader::igc_task_rec(const char* rec)
     } else {
       year += 1900;
     }
-    creation = QDateTime(QDate(year, month, day), QTime(hour, minute, second), Qt::UTC);
+    creation = QDateTime(QDate(year, month, day), QTime(hour, minute, second), QtUTC);
     if (!creation.isValid()) {
       fatal(MYNAME ": bad date time\n%s\n", rec);
     }
@@ -398,7 +398,7 @@ void IgcFormat::read()
         pres_wpt->fs.FsChainAdd(fsdata);
       }
 
-      pres_wpt->SetCreationTime(QDateTime(date, tod, Qt::UTC));
+      pres_wpt->SetCreationTime(QDateTime(date, tod, QtUTC));
 
       // Add the waypoint to the pressure altitude track
       if (pres_alt) {
index 8e38e6f8a0dd945fb2795881feacf9147402e656..9e12d39313717c77c096cb0732a8af005eb3308a 100644 (file)
@@ -246,7 +246,7 @@ LowranceusrFormat::lowranceusr4_writestr(const QString& buf, gbfile* file, int b
 gpsbabel::DateTime
 LowranceusrFormat::lowranceusr4_get_timestamp(unsigned int jd_number, unsigned int msecs)
 {
-  QDateTime qdt = QDateTime(QDate::fromJulianDay(jd_number), QTime(0, 0, 0), Qt::UTC).addMSecs(msecs);
+  QDateTime qdt = QDateTime(QDate::fromJulianDay(jd_number), QTime(0, 0, 0), QtUTC).addMSecs(msecs);
   return qdt;
 }
 
index ea7fcebbf913506af255a1091dce76483244b90d..3a2217c8503e26b398dd447f0fe98dfa6fc5d1a5 100644 (file)
@@ -839,7 +839,7 @@ int MtkLoggerBase::csv_line(gbfile* csvFile, int idx, unsigned long bmask, data_
               , (itm->rcr&0x0004)?"D":"", (itm->rcr&0x0008)?"B":"");
 
   if (bmask & (1U<<UTC)) {
-    QDateTime dt = QDateTime::fromSecsSinceEpoch(itm->timestamp, Qt::UTC);
+    QDateTime dt = QDateTime::fromSecsSinceEpoch(itm->timestamp, QtUTC);
     dt = dt.addMSecs(itm->timestamp_ms);
 
     QString timestamp = dt.toUTC().toString(u"yyyy/MM/dd,hh:mm:ss.zzz");
diff --git a/nmea.cc b/nmea.cc
index f07d78b9f88cc7dd4a341cd082663f64aede8b96..62f9062424b0da7f5dc8a476c65074f1495629ae 100644 (file)
--- a/nmea.cc
+++ b/nmea.cc
@@ -324,14 +324,14 @@ void
 NmeaFormat::nmea_set_waypoint_time(Waypoint* wpt, QDateTime* prev, const QDate& date, const QTime& time)
 {
   if (date.isValid()) {
-    wpt->SetCreationTime(QDateTime(date, time, Qt::UTC));
+    wpt->SetCreationTime(QDateTime(date, time, QtUTC));
     if (wpt->wpt_flags.fmt_use != 0) {
       wpt->wpt_flags.fmt_use = 0;
       without_date--;
     }
     *prev = wpt->GetCreationTime();
   } else if (prev->date().isValid()) {
-    wpt->SetCreationTime(QDateTime(prev->date(), time, Qt::UTC));
+    wpt->SetCreationTime(QDateTime(prev->date(), time, QtUTC));
     if (*prev > wpt->creation_time) {
       /* go over midnight ? */
       wpt->creation_time = wpt->creation_time.addDays(1);
@@ -342,7 +342,7 @@ NmeaFormat::nmea_set_waypoint_time(Waypoint* wpt, QDateTime* prev, const QDate&
     }
     *prev = wpt->GetCreationTime();
   } else {
-    wpt->SetCreationTime(QDateTime(QDate(), time, Qt::UTC));
+    wpt->SetCreationTime(QDateTime(QDate(), time, QtUTC));
     if (wpt->wpt_flags.fmt_use == 0) {
       wpt->wpt_flags.fmt_use = 1;
       without_date++;
@@ -639,7 +639,7 @@ NmeaFormat::gpzda_parse(const QString& ibuf)
 
     // The prev_datetime data member might be used by
     // nmea_fix_timestamps and nmea_set_waypoint_time.
-    prev_datetime = QDateTime(date, time, Qt::UTC);
+    prev_datetime = QDateTime(date, time, QtUTC);
   }
 }
 
@@ -839,7 +839,7 @@ NmeaFormat::nmea_fix_timestamps(route_head* track)
       return;
     }
 
-    QDateTime prev = QDateTime(opt_tm, QTime(0, 0), Qt::UTC);
+    QDateTime prev = QDateTime(opt_tm, QTime(0, 0), QtUTC);
 
     foreach (Waypoint* wpt, track->waypoint_list) {
 
index 9aa1027cdb97b5675cab20295f1fdeeb4b025f2e..feda00cbd3e29cf6090dce1b0205e9633bcead08 100644 (file)
Binary files a/reference/ricoh-rdc5300.jpg.jpg and b/reference/ricoh-rdc5300.jpg.jpg differ
diff --git a/reference/ricoh-rdc5300_offset.csv b/reference/ricoh-rdc5300_offset.csv
new file mode 100644 (file)
index 0000000..abac49f
--- /dev/null
@@ -0,0 +1,2 @@
+No,Latitude,Longitude,Name,Speed,utc_d,utc_t\r
+1,44.315150,15.265690,"ricoh-rdc5300",0.00,2000/05/31,22:50:40\r
diff --git a/reference/ricoh-rdc5300_offsettime.jpg b/reference/ricoh-rdc5300_offsettime.jpg
new file mode 100644 (file)
index 0000000..dc46e13
Binary files /dev/null and b/reference/ricoh-rdc5300_offsettime.jpg differ
diff --git a/reference/ricoh-rdc5300_offsettime.jpg.jpg b/reference/ricoh-rdc5300_offsettime.jpg.jpg
new file mode 100644 (file)
index 0000000..07aefa1
Binary files /dev/null and b/reference/ricoh-rdc5300_offsettime.jpg.jpg differ
index f6df657afd5267a11a2c308187d29040280211ed..2b272136757f761e7b4f185f8beab1f08c434078 100644 (file)
@@ -534,7 +534,7 @@ SkytraqBase::gpstime_to_qdatetime(int week, int sec) const
   int override = xstrtoi(opt_gps_utc_offset, nullptr, 10);
   if (override) {
     gps_timet -= override;
-    return QDateTime::fromSecsSinceEpoch(gps_timet, Qt::UTC);
+    return QDateTime::fromSecsSinceEpoch(gps_timet, QtUTC);
   }
 
   /* leap second compensation: */
@@ -557,7 +557,7 @@ SkytraqBase::gpstime_to_qdatetime(int week, int sec) const
   // Future: Consult http://maia.usno.navy.mil/ser7/tai-utc.dat
   // use http://www.stevegs.com/utils/jd_calc/ for Julian to UNIX sec
 
-  return QDateTime::fromSecsSinceEpoch(gps_timet, Qt::UTC);
+  return QDateTime::fromSecsSinceEpoch(gps_timet, QtUTC);
 }
 
 void
index 579c50089f863c8f5b0f7dec479b19c08393356c..30962f23b8e9cf4d6deaea10ea57282c131aaf3d 100644 (file)
@@ -29,6 +29,9 @@
 #include <QtGlobal>
 #include <QDateTime>
 #include <QString>
+#ifdef LIGHTWEIGHT_TIMEZONES_SUPPORTED
+#include <QTimeZone>
+#endif
 
 // As this code began in C, we have several hundred places that set and
 // read creation_time as a time_t.  Provide some operator overloads to make
@@ -54,7 +57,11 @@ public:
   // Qt::LocalTime compared to Qt::UTC on ubuntu bionic.
   // Note that these conversions can be required if the Qt::TimeSpec is
   // set to Qt:LocalTime after construction.
+#ifdef LIGHTWEIGHT_TIMEZONES_SUPPORTED
+  DateTime() : QDateTime(QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC))
+#else
   DateTime() : QDateTime(QDateTime::fromMSecsSinceEpoch(0, Qt::UTC))
+#endif
   {
   }
 
index ee6116b5818aad6a2575b421354912470e2bb44c..062e690b456b354b1c117acae1f5c39b164b81a6 100644 (file)
--- a/subrip.cc
+++ b/subrip.cc
@@ -221,7 +221,7 @@ SubripFormat::wr_init(const QString& fname)
         fatal(FatalMsg().nospace() << MYNAME ": option gps_time value (" << opt_gpstime << ") is invalid.  Expected hhmmss[.sss]");
       }
     }
-    gps_datetime = QDateTime(gps_date, gps_time, Qt::UTC);
+    gps_datetime = QDateTime(gps_date, gps_time, QtUTC);
   }
 
   video_offset_ms = 0;
index 26c39b29b16cfed4c917a406fbd8580fd3eae895..6cd71360e70429c462aa7b336d2e2d6c5cc6c354 100644 (file)
@@ -23,6 +23,56 @@ bincompare ${REFERENCE}/kodak-dc210.jpg.jpg ${TMPDIR}/kodak-dc210.jpg.jpg
 # test a big endian image
 # image from   https://github.com/ianare/exif-samples.git
 cp ${REFERENCE}/ricoh-rdc5300.jpg ${TMPDIR}/ricoh-rdc5300.jpg
-gpsbabel -i unicsv -f ${REFERENCE}/IMG_2065_retag.csv -o exif,name=IMG_2065 -F ${TMPDIR}/ricoh-rdc5300.jpg
+gpsbabel -i unicsv -f ${REFERENCE}/ricoh-rdc5300_offset.csv -o exif,name=ricoh-rdc5300 -F ${TMPDIR}/ricoh-rdc5300.jpg
 bincompare ${REFERENCE}/ricoh-rdc5300.jpg.jpg ${TMPDIR}/ricoh-rdc5300.jpg.jpg
 
+# test offset option. photo has no gps info and no exif offset tags.
+# the offset is only required if the current system timezone is differnt from utc.
+# cat reference/ricoh-rdc5300_offset.csv
+# No,Latitude,Longitude,Name,Speed,utc_d,utc_t
+# 1,44.315150,15.265690,"ricoh-rdc5300",0.00,2000/05/31,22:50:40
+# $ exiftool -D -G -time:all -composite:GPSPosition -c "%+.6f" reference/ricoh-rdc5300.jpg
+# [File]              - File Modification Date/Time     : 2024:09:27 07:18:42-06:00
+# [File]              - File Access Date/Time           : 2024:09:28 07:19:24-06:00
+# [File]              - File Inode Change Date/Time     : 2024:09:27 07:18:42-06:00
+# [EXIF]          36867 Date/Time Original              : 2000:05:31 21:50:40
+# [EXIF]          36868 Create Date                     : 2000:05:31 21:50:40
+# $ exiftool -D -G -time:all -composite:GPSPosition -c "%+.6f" reference/ricoh-rdc5300.jpg.jpg
+# [File]              - File Modification Date/Time     : 2024:09:29 07:04:04-06:00
+# [File]              - File Access Date/Time           : 2024:09:29 07:04:06-06:00
+# [File]              - File Inode Change Date/Time     : 2024:09:29 07:04:04-06:00
+# [EXIF]          36867 Date/Time Original              : 2000:05:31 21:50:40
+# [EXIF]          36868 Create Date                     : 2000:05:31 21:50:40
+# [EXIF]              7 GPS Time Stamp                  : 22:50:40
+# [EXIF]             29 GPS Date Stamp                  : 2000:05:31
+# [Composite]         - GPS Date/Time                   : 2000:05:31 22:50:40Z
+# [Composite]         - GPS Position                    : +44.315150, +15.265690
+cp ${REFERENCE}/ricoh-rdc5300.jpg ${TMPDIR}/ricoh-rdc5300_offset.jpg
+gpsbabel -i unicsv -f ${REFERENCE}/ricoh-rdc5300_offset.csv -o exif,offset="-01:00" -F ${TMPDIR}/ricoh-rdc5300_offset.jpg
+bincompare ${REFERENCE}/ricoh-rdc5300.jpg.jpg ${TMPDIR}/ricoh-rdc5300_offset.jpg.jpg
+
+# prove the option value is handled the same as the OffsetTimeOriginal tag.
+# $ exiftool -D -G -time:all -composite:GPSPosition -c "%+.6f" reference/ricoh-rdc5300_offsettime.jpg
+# [File]              - File Modification Date/Time     : 2024:09:29 06:32:54-06:00
+# [File]              - File Access Date/Time           : 2024:09:29 06:33:20-06:00
+# [File]              - File Inode Change Date/Time     : 2024:09:29 06:32:54-06:00
+# [EXIF]          36867 Date/Time Original              : 2000:05:31 21:50:40
+# [EXIF]          36868 Create Date                     : 2000:05:31 21:50:40
+# [EXIF]          36881 Offset Time Original            : -01:00
+# [Composite]         - Date/Time Original              : 2000:05:31 21:50:40-01:00
+# $ exiftool -D -G -time:all -composite:GPSPosition -c "%+.6f" reference/ricoh-rdc5300_offsettime.jpg.jpg
+# [File]              - File Modification Date/Time     : 2024:09:29 07:09:20-06:00
+# [File]              - File Access Date/Time           : 2024:09:29 07:09:53-06:00
+# [File]              - File Inode Change Date/Time     : 2024:09:29 07:09:20-06:00
+# [EXIF]          36867 Date/Time Original              : 2000:05:31 21:50:40
+# [EXIF]          36868 Create Date                     : 2000:05:31 21:50:40
+# [EXIF]          36881 Offset Time Original            : -01:00
+# [EXIF]              7 GPS Time Stamp                  : 22:50:40
+# [EXIF]             29 GPS Date Stamp                  : 2000:05:31
+# [Composite]         - Date/Time Original              : 2000:05:31 21:50:40-01:00
+# [Composite]         - GPS Date/Time                   : 2000:05:31 22:50:40Z
+# [Composite]         - GPS Position                    : +44.315150, +15.265690
+cp ${REFERENCE}/ricoh-rdc5300_offsettime.jpg ${TMPDIR}/ricoh-rdc5300_offsettime.jpg
+gpsbabel -i unicsv -f ${REFERENCE}/ricoh-rdc5300_offset.csv -o exif -F ${TMPDIR}/ricoh-rdc5300_offsettime.jpg
+bincompare ${REFERENCE}/ricoh-rdc5300_offsettime.jpg.jpg ${TMPDIR}/ricoh-rdc5300_offsettime.jpg.jpg
+
index 611aeb2917969f3bfe1cea7322ccfcb06d9f5ddf..246787f5656c1aa1bfd66105475385acfc5e664b 100755 (executable)
@@ -19,6 +19,9 @@ remove=( \
 debug_info \
 qtcharts \
 qtdatavis3d \
+qtgraphs \
+qtgrpc \
+qthttpserver \
 qtlottie \
 qtnetworkauth \
 qtquick3d \
@@ -40,6 +43,9 @@ do
       skip=true
     fi
   done
+  if [[ "$a" == *".debug_information" ]]; then
+    skip=true
+  fi
   if [ $skip == false ]; then
     mods+=( "$a" )
   fi
index 1f2cad96c77e20db29401ed9f570148e6147a630..7753a2b38907bc109e2a93c9b10bdb69ee636a16 100755 (executable)
@@ -30,6 +30,8 @@ elif [ "${COMPILER}" = "msvc2019_64" ]; then
   PACKAGE_SUFFIX=win64_msvc2019_64
 elif [ "${COMPILER}" = "msvc2019" ]; then
   PACKAGE_SUFFIX=win32_msvc2019
+elif [ "${COMPILER}" = "msvc2022_64" ]; then
+  PACKAGE_SUFFIX=win64_msvc2022_64
 else
   echo "ERROR: unrecognized Qt compiler ${COMPILER}." >&2
   exit 1
index 7222bc86d1f95c1ad5383957b0485b8957f6acdb..a59d49890e0800665e1098c3d1e1f7597755ad0f 100755 (executable)
@@ -17,7 +17,10 @@ if [ $# -ge 3 ]; then
     GENERATOR[1]=$3
   fi
 fi
-if version_ge "${QTVER}" 6.5.0; then
+if version_ge "${QTVER}" 6.8.0; then
+  DEPLOY_TARGET="12.0"
+  ARCHS="x86_64;arm64"
+elif version_ge "${QTVER}" 6.5.0; then
   DEPLOY_TARGET="11.0"
   ARCHS="x86_64;arm64"
 elif version_ge "${QTVER}" 6.0.0; then
index 06f7c8bf3d75ca7ad154a1792cdf29e97cffaf3c..835cd60999b94705add53d705c9fe98d34597ff0 100644 (file)
@@ -41,6 +41,9 @@ static constexpr bool TRACKF_DBG = false;
 #include <QRegularExpression>              // for QRegularExpression, QRegularExpression::CaseInsensitiveOption, QRegularExpression::PatternOptions
 #include <QRegularExpressionMatch>         // for QRegularExpressionMatch
 #include <QString>                         // for QString
+#ifdef LIGHTWEIGHT_TIMEZONES_SUPPORTED
+#include <QTimeZone>                       // for QTimeZone
+#endif
 #include <Qt>                              // for UTC, CaseInsensitive
 #include <QtGlobal>                        // for foreach, qPrintable, QAddConst<>::Type, qint64
 
@@ -298,7 +301,7 @@ void TrackFilter::trackfilter_title()
     fatal(MYNAME "-title: Missing your title!\n");
   }
   for (auto* track : std::as_const(track_list)) {
-    trackfilter_pack_init_rte_name(track, QDateTime::fromMSecsSinceEpoch(0, Qt::UTC));
+    trackfilter_pack_init_rte_name(track, QDateTime::fromMSecsSinceEpoch(0, QtUTC));
   }
 }
 
@@ -676,7 +679,11 @@ QDateTime TrackFilter::trackfilter_range_check(const char* timestr)
   if (match.hasMatch()) {
     // QTime::fromString zzz expects exactly 3 digits representing milliseconds.
     result = QDateTime::fromString(match.captured(0), u"yyyyMMddHHmmss.zzz");
+#ifdef LIGHTWEIGHT_TIMEZONES_SUPPORTED
+    result.setTimeZone(QTimeZone::UTC);
+#else
     result.setTimeSpec(Qt::UTC);
+#endif
     if (!result.isValid()) {
       fatal(MYNAME "-range-check: Invalid timestamp \"%s\"!\n", timestr);
     }
@@ -834,7 +841,11 @@ TrackFilter::faketime_t TrackFilter::trackfilter_faketime_check(const char* time
     QString fmtstart("00000101000000");
     fmtstart.replace(0, start.size(), start);
     result.start = QDateTime::fromString(fmtstart, u"yyyyMMddHHmmss");
+#ifdef LIGHTWEIGHT_TIMEZONES_SUPPORTED
+    result.start.setTimeZone(QTimeZone::UTC);
+#else
     result.start.setTimeSpec(Qt::UTC);
+#endif
     if (!result.start.isValid()) {
       fatal(MYNAME "-faketime-check: Invalid timestamp \"%s\"!\n", qPrintable(start));
     }
diff --git a/util.cc b/util.cc
index 53e3b983fdda7b586b2366c9a741f290eac487ed..bf54ad498d124bc3323393b038ea4eea8b826d4b 100644 (file)
--- a/util.cc
+++ b/util.cc
@@ -294,6 +294,31 @@ QDateTime
 make_datetime(QDate date, QTime time, bool is_localtime, bool force_utc, int utc_offset)
 {
   QDateTime result;
+#ifdef LIGHTWEIGHT_TIMEZONES_SUPPORTED
+  QTimeZone timezone;
+
+  if (is_localtime) {
+    if (force_utc) { // override with passed option value
+      timezone = QTimeZone::fromSecondsAheadOfUtc(utc_offset);
+    } else {
+      timezone = QTimeZone::LocalTime;
+    }
+  } else {
+    timezone = QTimeZone::UTC;
+  }
+
+  if (date.isValid() && time.isValid()) {
+    result = QDateTime(date, time, timezone);
+  } else if (time.isValid()) {
+    // TODO: Wouldn't it be better to return an invalid QDateTime
+    // that contained an invalid QDate, a valid QTime and a valid
+    // Qt::TimeSpec?
+    result = QDateTime(QDate(1970, 1, 1), time, timezone);
+  } else if (date.isValid()) {
+    //  no time, use start of day in the given Qt::TimeSpec.
+    result = date.startOfDay(timezone);
+  }
+#else
   Qt::TimeSpec timespec;
   int offset = 0;
 
@@ -326,6 +351,7 @@ make_datetime(QDate date, QTime time, bool is_localtime, bool force_utc, int utc
     result = date.startOfDay(timespec, offset);
   }
 
+#endif
   return result;
 }
 
@@ -347,7 +373,7 @@ gpsbabel::DateTime
 current_time()
 {
   if (gpsbabel_testmode()) {
-    return QDateTime::fromMSecsSinceEpoch(0, Qt::UTC);
+    return QDateTime::fromMSecsSinceEpoch(0, QtUTC);
   }
 
   return QDateTime::currentDateTimeUtc();
@@ -361,14 +387,14 @@ current_time()
  */
 QDateTime dotnet_time_to_qdatetime(long long dotnet)
 {
-  QDateTime epoch = QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), Qt::UTC);
+  QDateTime epoch = QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), QtUTC);
   qint64 millisecs = (dotnet + 5000)/ 10000;
   return epoch.addMSecs(millisecs);
 }
 
 long long qdatetime_to_dotnet_time(const QDateTime& dt)
 {
-  QDateTime epoch = QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), Qt::UTC);
+  QDateTime epoch = QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), QtUTC);
   qint64 millisecs = epoch.msecsTo(dt);
   return millisecs * 10000;
 }
diff --git a/v900.cc b/v900.cc
index 4b8fb942e95e6fd2b84a187b59d5ea521ace2dd2..baf5a326b537913e4923ce074af56bb7eacd13cb 100644 (file)
--- a/v900.cc
+++ b/v900.cc
@@ -143,7 +143,7 @@ V900Format::bintime2utc(int date, int time) {
   // What's left in 'date' is year.
   QDate dt(date + 2000, month, day);
 
-  return QDateTime(dt, tm, Qt::UTC);
+  return QDateTime(dt, tm, QtUTC);
 }
 
 void